import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:wis_flutter/common/ConstantsUtils.dart';
import 'package:wis_flutter/common/DataResult.dart';
import 'package:wis_flutter/common/LocalStorage.dart';
import 'package:wis_flutter/common/http/HTTPCode.dart';
import 'package:wis_flutter/common/http/interceptor/ErrorInterceptors.dart';
import 'package:wis_flutter/common/http/interceptor/HeaderInterceptors.dart';
import 'package:wis_flutter/common/http/interceptor/LogsInterceptors.dart';
import 'package:wis_flutter/common/http/interceptor/ResponseInterceptors.dart';
import 'package:wis_flutter/common/http/interceptor/TokenInterceptors.dart';


class HttpManage {

  static Dio _dio;

  factory HttpManage() => _getInstance();

  static HttpManage get instance => _getInstance();
  static HttpManage _instance;
  static InterceptorsWrapper _tokenInterceptor ;

  HttpManage.initHttp(){
    _dio = new Dio(); // 使用默认配置
    _dio.interceptors.add(new HeaderInterceptors());
    _dio.interceptors.add(getTokenInterceptor());
    _dio.interceptors.add(new LogsInterceptors());
    _dio.interceptors.add(new ErrorInterceptors(_dio));
    _dio.interceptors.add(new ResponseInterceptors());
  }

  static setTokenInterceptor(InterceptorsWrapper tokenInterceptor){
    if(tokenInterceptor != null){
      _tokenInterceptor = tokenInterceptor;
    }
  }
  static InterceptorsWrapper getTokenInterceptor(){
    if(_tokenInterceptor != null){
      return _tokenInterceptor;
    }
    return  new TokenInterceptors();
  }

  static HttpManage _getInstance() {
    if (_instance == null) {
      _instance = new HttpManage.initHttp();
    }
    return _instance;
  }
  static Dio getInitDio(){
    HttpManage._getInstance();
    return _dio;
  }

  static const CONTENT_TYPE_JSON = "application/json";
  static const CONTENT_TYPE_FORM = "application/x-www-form-urlencoded";

  static login(userName, password, lang, url) async {
    HttpManage manage = HttpManage._getInstance();
    DataResult result = await manage.commonLogin(userName, password, lang, url);
    return result;
  }

  static request(url, params, Options option) async {
    HttpManage manage = HttpManage._getInstance();
    return await manage.commonRequest(url, params, option);
  }

  commonLogin(userName, password, lang, url) async {
    Map requestParams = {
      'lang': lang,
      'username': userName,
      'password': password,
    };
    DataResult result = await request(
        url, requestParams, new Options(method: "post"));
    if (result.success) {
      String _token = 'Bearer ' + result.data["token"];
      await LocalStorage.save(ConstantsUtils.TOKEN_KEY, _token);
      await LocalStorage.save(
          ConstantsUtils.STORAGE_CODE_USER_INFO, json.encode(result.data));
    }
    return result;
  }

  commonRequest(url, params, Options option, {noTip = false}) async {
    option = option ?? new Options(method: "get");
    option.contentType = option.contentType ??"application/x-www-form-urlencoded";
    option.responseType = ResponseType.json;

    _resultError(DioError e) {
      Response res = e.response != null ? e.response : new Response(
          statusCode: 666);
      if (e.type == DioErrorType.CONNECT_TIMEOUT ||
          e.type == DioErrorType.RECEIVE_TIMEOUT) {
        res.statusCode = HTTPCode.NETWORK_TIMEOUT;
      }
      return new DataResult(
          false, HTTPCode.errorHandleFunction(res.statusCode, e.message),
          res.statusCode.toString());
    }

    Response response;
    try {
      response = await _dio.request(url, data: params, options: option);
    } on DioError catch (e) {
      return _resultError(e);
    }
    if (response.data is DioError) {
      return _resultError(response.data);
    }
    if (response.data == null) {
      return null;
    }
    return response.data;
  }

  static download(url, name,BuildContext context,{token:false}) async{
    if(token){
      HttpManage._getInstance();
    }else{
      _dio=new Dio();
    }

    String _localPath = ( await _findLocalPath(context)) + '/Download';
    return await _dio.download(url, _localPath + "/" + name);
  }
  static Future<String>  _findLocalPath(context) async {
    final directory = Theme.of(context).platform == TargetPlatform.android
        ? await getExternalStorageDirectory()
        : await getApplicationDocumentsDirectory();
    return directory.path;
  }

  static upload (url,{token:true}) async{
    if(token){
      HttpManage._getInstance();
    }else{
      _dio=new Dio();
    }

    File file = await FilePicker.getFile(type: FileType.any);
    if(file != null){
      var name = file.path.substring(file.path.lastIndexOf("/") + 1, file.path.length);
      var postData = FormData.fromMap({
        "thumb": await MultipartFile.fromFile(
            file.path, filename: name)
      });
      var responce = await _dio.post(url,data:postData,onSendProgress: (int sent, int total) {
        print("$sent $total");
      },);
      return responce;
    }
    return null;

  }


}